From 41bfb22834f0cd13166914b35d4616f21f3c99df Mon Sep 17 00:00:00 2001 From: Lukas Pioch Date: Fri, 5 May 2017 11:58:21 +0200 Subject: Corrected brewingstand and added support for fuel --- Server/Plugins/APIDump/Classes/BlockEntities.lua | 35 ++++++ src/BlockEntities/BrewingstandEntity.cpp | 63 +++++++--- src/BlockEntities/BrewingstandEntity.h | 22 +++- src/BrewingRecipes.cpp | 8 ++ src/BrewingRecipes.h | 5 +- src/UI/BrewingstandWindow.cpp | 8 +- src/UI/SlotArea.cpp | 147 ++++++++++++----------- src/UI/SlotArea.h | 2 +- src/WorldStorage/NBTChunkSerializer.cpp | 1 + src/WorldStorage/WSSAnvil.cpp | 12 +- 10 files changed, 204 insertions(+), 99 deletions(-) diff --git a/Server/Plugins/APIDump/Classes/BlockEntities.lua b/Server/Plugins/APIDump/Classes/BlockEntities.lua index bae9030c4..5f1289f1e 100644 --- a/Server/Plugins/APIDump/Classes/BlockEntities.lua +++ b/Server/Plugins/APIDump/Classes/BlockEntities.lua @@ -441,6 +441,26 @@ return }, Notes = "Returns the item in the right bottle slot", }, + GetFuelSlot = + { + Returns = + { + { + Type = "cItem", + }, + }, + Notes = "Returns the item in the top left fuel slot", + }, + GetRemainingFuel = + { + Returns = + { + { + Type = "number", + }, + }, + Notes = "Returns the remaining fuel that is left. It's the amount of brewing operations that can be done (20 for one blaze powder).", + }, GetTimeBrewed = { Returns = @@ -495,6 +515,17 @@ return }, Notes = "Sets the item in the right bottle slot", }, + SetFuelSlot = + { + Params = + { + { + Name = "FuelSlot", + Type = "cItem", + }, + }, + Notes = "Sets the item in the top left fuel slot", + }, }, Constants = { @@ -514,6 +545,10 @@ return { Notes = "Index of the right bottle slot", }, + bsFuel = + { + Notes = "Index of the top left fuel slot", + }, ContentsHeight = { Notes = "Height (Y) of the {{cItemGrid|cItemGrid}} representing the contents", diff --git a/src/BlockEntities/BrewingstandEntity.cpp b/src/BlockEntities/BrewingstandEntity.cpp index f202ab419..e357dbf98 100644 --- a/src/BlockEntities/BrewingstandEntity.cpp +++ b/src/BlockEntities/BrewingstandEntity.cpp @@ -24,7 +24,8 @@ cBrewingstandEntity::cBrewingstandEntity(int a_BlockX, int a_BlockY, int a_Block m_BlockMeta(a_BlockMeta), m_IsDestroyed(false), m_IsBrewing(false), - m_TimeBrewed(0) + m_TimeBrewed(0), + m_RemainingFuel(0) { m_Contents.AddListener(*this); for (int i = 0; i < 3; i++) @@ -76,6 +77,7 @@ bool cBrewingstandEntity::UsedBy(cPlayer * a_Player) { BroadcastProgress(0, 0); } + BroadcastProgress(1, m_RemainingFuel); return true; } @@ -95,12 +97,11 @@ bool cBrewingstandEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) // The necessary brewing time, has been reached if (m_TimeBrewed >= m_NeedBrewingTime) { - const cBrewingRecipes::cRecipe * Recipe = nullptr; BroadcastProgress(0, 0); m_IsBrewing = false; m_TimeBrewed = 0; - // Return if the hook has been canceled + // Return if the hook has been cancelled if (cPluginManager::Get()->CallHookBrewingCompleting(*m_World, *this)) { return false; @@ -111,7 +112,27 @@ bool cBrewingstandEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) Ingredient.m_ItemCount -= 1; m_Contents.SetSlot(bsIngredient, Ingredient); + // Fuel slot + m_RemainingFuel--; + if (m_RemainingFuel <= 0) + { + if (!m_Contents.GetSlot(bsFuel).IsEmpty()) + { + cItem Fuel = m_Contents.GetSlot(bsFuel); + Fuel.m_ItemCount -= 1; + m_Contents.SetSlot(bsFuel, Fuel); + m_RemainingFuel = 20; + BroadcastProgress(1, m_RemainingFuel); + } + } + else + { + BroadcastProgress(1, m_RemainingFuel); + } + + // Loop over all bottle slots and update available bottles + const cBrewingRecipes::cRecipe * Recipe = nullptr; for (int i = 0; i < 3; i++) { if (m_Contents.GetSlot(i).IsEmpty() || (m_CurrentBrewingRecipes[i] == nullptr)) @@ -125,7 +146,6 @@ bool cBrewingstandEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) // Brewing process completed cPluginManager::Get()->CallHookBrewingCompleted(*m_World, *this); - return true; } @@ -174,6 +194,26 @@ void cBrewingstandEntity::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) ASSERT(a_ItemGrid == &m_Contents); + // Check for fuel + if (m_RemainingFuel <= 0) + { + if (GetSlot(bsFuel).IsEmpty()) + { + // No remaining fuel stop brewing and bail out + m_IsBrewing = false; + return; + } + else + { + // Fuel is available, refill + m_RemainingFuel = 20; + BroadcastProgress(1, m_RemainingFuel); + cItem Fuel = m_Contents.GetSlot(bsFuel); + Fuel.m_ItemCount -= 1; + m_Contents.SetSlot(bsFuel, Fuel); + } + } + // Check if still a item is in the ingredient slot if (GetSlot(bsIngredient).IsEmpty()) { @@ -258,19 +298,10 @@ void cBrewingstandEntity::UpdateProgressBars(bool a_ForceUpdate) -void cBrewingstandEntity::setTimeBrewed(short a_TimeBrewed) -{ - m_TimeBrewed = a_TimeBrewed; -} - - - - - void cBrewingstandEntity::ContinueBrewing(void) { // Continue brewing if number is greater than 0 - if (m_TimeBrewed > 0) + if ((m_TimeBrewed > 0) && (m_RemainingFuel > 0)) { m_IsBrewing = true; } @@ -280,9 +311,9 @@ void cBrewingstandEntity::ContinueBrewing(void) -void cBrewingstandEntity::GetRecipes(void) +void cBrewingstandEntity::LoadRecipes(void) { - if (GetSlot(3).IsEmpty()) + if (GetSlot(bsIngredient).IsEmpty()) { return; } diff --git a/src/BlockEntities/BrewingstandEntity.h b/src/BlockEntities/BrewingstandEntity.h index 89f836e71..efdf72daf 100644 --- a/src/BlockEntities/BrewingstandEntity.h +++ b/src/BlockEntities/BrewingstandEntity.h @@ -27,8 +27,9 @@ public: bsMiddleBottle = 1, // Middle bottle slot number bsRightBottle = 2, // Right bottle slot number bsIngredient = 3, // Top ingredient slot number + bsFuel = 4, // Top left fuel slot number - ContentsWidth = 4, + ContentsWidth = 5, ContentsHeight = 1, }; @@ -59,6 +60,9 @@ public: /** Returns the time that the current items has been brewing, in ticks */ short GetTimeBrewed(void) { return m_TimeBrewed; } + /** Returns the remaining fuel that is left. */ + short GetRemainingFuel(void) { return m_RemainingFuel; } + /** Returns the item in the left bottle slot */ const cItem & GetLeftBottleSlot(void) const { return GetSlot(bsLeftBottle); } @@ -71,6 +75,9 @@ public: /** Returns the item in the ingredient slot */ const cItem & GetIndgredientSlot(void) const { return GetSlot(bsIngredient); } + /** Returns the item in the fuel slot. */ + const cItem & GetFuelSlot(void) const { return GetSlot(bsFuel); } + /** Get the expected result item for the given slot number */ const cItem & GetResultItem(int a_SlotNumber) { return m_Results[a_SlotNumber]; } @@ -86,16 +93,22 @@ public: /** Sets the item in the ingredient slot */ void SetIngredientSlot(const cItem & a_Item) { SetSlot(bsIngredient, a_Item); } + /** Sets the item in the fuel slot */ + void SetFuelSlot(const cItem & a_Item) { SetSlot(bsFuel, a_Item); } + // tolua_end /** Sets the current brewing time. Will be called if the brewing stand gets loaded from the world. */ - void setTimeBrewed(short a_TimeBrewed); + void SetTimeBrewed(short a_TimeBrewed) { m_TimeBrewed = a_TimeBrewed; } + + /** Sets the remaining fuel. Will be called if the brewing stand gets loaded from the world. */ + void SetRemainingFuel(short a_RemainingFuel) { m_RemainingFuel = a_RemainingFuel; } /** Starts the brewing proccess. Will be called if the brewing stand gets loaded from the world. */ void ContinueBrewing(void); /** Gets the recipes. Will be called if the brewing stand gets loaded from the world. */ - void GetRecipes(void); + void LoadRecipes(void); protected: /** Block meta of the block currently represented by this entity */ @@ -119,6 +132,9 @@ protected: /** Amount of ticks that the current item has been brewed */ short m_TimeBrewed; + /** The remaining fuel for the brewing stand. It's the amount of brewing operations that can be done. */ + short m_RemainingFuel; + /** Sends the specified progressbar value to all clients of the window */ void BroadcastProgress(short a_ProgressbarID, short a_Value); diff --git a/src/BrewingRecipes.cpp b/src/BrewingRecipes.cpp index 3ee39c8af..4c127649a 100644 --- a/src/BrewingRecipes.cpp +++ b/src/BrewingRecipes.cpp @@ -285,3 +285,11 @@ bool cBrewingRecipes::IsBottle(const cItem & a_Item) const +bool cBrewingRecipes::IsFuel(const cItem & a_Item) const +{ + return (a_Item.m_ItemType == E_ITEM_BLAZE_POWDER); +} + + + + diff --git a/src/BrewingRecipes.h b/src/BrewingRecipes.h index 82fb0b822..f42384896 100644 --- a/src/BrewingRecipes.h +++ b/src/BrewingRecipes.h @@ -39,7 +39,10 @@ public: bool IsIngredient(const cItem & a_Ingredient) const; /** Returns true if the item is a bottle / potion, false if not. */ - bool IsBottle(const cItem & a_Bottle) const; + bool IsBottle(const cItem & a_Item) const; + + /** Returns true if the item is the fuel, false if not. */ + bool IsFuel(const cItem & a_Item) const; private: void ClearRecipes(void); diff --git a/src/UI/BrewingstandWindow.cpp b/src/UI/BrewingstandWindow.cpp index 2f1f3c97d..11a5990f2 100644 --- a/src/UI/BrewingstandWindow.cpp +++ b/src/UI/BrewingstandWindow.cpp @@ -31,17 +31,15 @@ void cBrewingstandWindow::DistributeStack(cItem & a_ItemStack, int a_Slot, cPlay if (a_ClickedArea == m_SlotAreas[0]) { - // Brewing stand Area - if ((a_Slot >= 0) && (a_Slot < 3)) + if ((a_Slot >= 0) && (a_Slot <= 4)) { - // Bottle slots + // Brewing stand Area AreasInOrder.push_back(m_SlotAreas[2]); /* Hotbar */ AreasInOrder.push_back(m_SlotAreas[1]); /* Inventory */ super::DistributeStackToAreas(a_ItemStack, a_Player, AreasInOrder, a_ShouldApply, true); } else { - // Ingredient slot AreasInOrder.push_back(m_SlotAreas[1]); /* Inventory */ AreasInOrder.push_back(m_SlotAreas[2]); /* Hotbar */ super::DistributeStackToAreas(a_ItemStack, a_Player, AreasInOrder, a_ShouldApply, false); @@ -50,7 +48,7 @@ void cBrewingstandWindow::DistributeStack(cItem & a_ItemStack, int a_Slot, cPlay else { cBrewingRecipes * BR = cRoot::Get()->GetBrewingRecipes(); - if ((BR->IsBottle(a_ItemStack)) || (BR->IsIngredient(a_ItemStack))) + if ((BR->IsBottle(a_ItemStack)) || (BR->IsIngredient(a_ItemStack)) || BR->IsFuel(a_ItemStack)) { AreasInOrder.push_back(m_SlotAreas[0]); /* brewing stand Area */ } diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 3a01d78ef..71a43e01d 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -1947,7 +1947,7 @@ void cSlotAreaFurnace::HandleSmeltItem(const cItem & a_Result, cPlayer & a_Playe //////////////////////////////////////////////////////////////////////////////// // cSlotAreaBrewingstand: cSlotAreaBrewingstand::cSlotAreaBrewingstand(cBrewingstandEntity * a_Brewingstand, cWindow & a_ParentWindow) : - cSlotArea(4, a_ParentWindow), + cSlotArea(5, a_ParentWindow), m_Brewingstand(a_Brewingstand) { m_Brewingstand->GetContents().AddListener(*this); @@ -1975,100 +1975,101 @@ void cSlotAreaBrewingstand::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAct return; } - if ((a_SlotNum >= 0) && (a_SlotNum < 3)) + if (GetSlot(a_SlotNum, a_Player) == nullptr) { - bool bAsync = false; - if (GetSlot(a_SlotNum, a_Player) == nullptr) - { - LOGWARNING("GetSlot(%d) returned nullptr! Ignoring click", a_SlotNum); - return; - } + LOGWARNING("GetSlot(%d) returned nullptr! Ignoring click", a_SlotNum); + return; + } - cItem Slot(*GetSlot(a_SlotNum, a_Player)); - if (!Slot.IsSameType(a_ClickedItem)) - { - LOGWARNING("*** Window lost sync at item %d in SlotArea with %d items ***", a_SlotNum, m_NumSlots); - LOGWARNING("My item: %s", ItemToFullString(Slot).c_str()); - LOGWARNING("Their item: %s", ItemToFullString(a_ClickedItem).c_str()); - bAsync = true; - } + cItem Slot(*GetSlot(a_SlotNum, a_Player)); + cItem & DraggingItem = a_Player.GetDraggingItem(); + cBrewingRecipes * BR = cRoot::Get()->GetBrewingRecipes(); + if ((a_SlotNum >= 0) && (a_SlotNum <= 2)) + { + // Bottle slots switch (a_ClickAction) { + case caLeftClick: + case caRightClick: + { + if (BR->IsBottle(Slot)) + { + HandleBrewedItem(a_Player, Slot); + } + if (!DraggingItem.IsEmpty() && !BR->IsBottle(DraggingItem)) + { + // Deny placing a invalid item into the bottle slot + return; + } + break; + } case caShiftLeftClick: case caShiftRightClick: { - HandleBrewedItem(a_Player); - ShiftClicked(a_Player, a_SlotNum, Slot); - return; + if (BR->IsBottle(Slot)) + { + HandleBrewedItem(a_Player, Slot); + } + super::ShiftClicked(a_Player, a_SlotNum, Slot); + break; } - case caMiddleClick: + default: { - MiddleClicked(a_Player, a_SlotNum); - return; + if (!DraggingItem.IsEmpty() && !BR->IsBottle(DraggingItem)) + { + // Deny placing a invalid item into the bottle slot + return; + } + break; } - case caDropKey: - case caCtrlDropKey: + } + } + + if ((a_SlotNum == 3) && !DraggingItem.IsEmpty()) + { + // Ingredient slot + switch (a_ClickAction) + { + case caShiftLeftClick: + case caShiftRightClick: { - DropClicked(a_Player, a_SlotNum, (a_SlotNum == caCtrlDropKey)); - Slot.m_ItemCount = Slot.m_ItemCount - GetSlot(a_SlotNum, a_Player)->m_ItemCount; - HandleBrewedItem(a_Player); - return; + super::ShiftClicked(a_Player, a_SlotNum, Slot); + break; } default: { + if (!BR->IsIngredient(DraggingItem)) + { + // Deny placing a invalid item into the ingredient slot + return; + } break; } } + } - cItem & DraggingItem = a_Player.GetDraggingItem(); - if (!DraggingItem.IsEmpty()) - { - super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem); - return; - } - else + if ((a_SlotNum == 4) && !DraggingItem.IsEmpty()) + { + // Fuel slot + switch (a_ClickAction) { - switch (a_ClickAction) + case caShiftLeftClick: + case caShiftRightClick: { - case caDblClick: + super::ShiftClicked(a_Player, a_SlotNum, Slot); + break; + } + default: + { + if (!BR->IsFuel(DraggingItem)) { - DblClicked(a_Player, a_SlotNum); + // Deny placing a invalid item into the fuel slot return; } - case caLeftClick: - { - DraggingItem = Slot; - HandleBrewedItem(a_Player); - Slot.Empty(); - break; - } - case caRightClick: - { - DraggingItem = Slot.CopyOne(); - DraggingItem.m_ItemCount = static_cast(static_cast(Slot.m_ItemCount) / 2.f + 0.5f); - Slot.m_ItemCount -= DraggingItem.m_ItemCount; - - if (Slot.m_ItemCount <= 0) - { - Slot.Empty(); - } - HandleBrewedItem(a_Player); - break; - } - default: - { - ASSERT(!"Unhandled click type!"); - } + break; } } - - SetSlot(a_SlotNum, a_Player, Slot); - if (bAsync) - { - m_ParentWindow.BroadcastWholeWindow(); - } - return; } super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem); @@ -2078,9 +2079,13 @@ void cSlotAreaBrewingstand::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAct -void cSlotAreaBrewingstand::HandleBrewedItem(cPlayer & a_Player) +void cSlotAreaBrewingstand::HandleBrewedItem(cPlayer & a_Player, const cItem & a_ClickedItem) { - a_Player.AwardAchievement(achBrewPotion); + // Award an achievement if the item is not a water bottle (is a real brewed potion) + if (a_ClickedItem.m_ItemDamage > 0) + { + a_Player.AwardAchievement(achBrewPotion); + } } diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h index f613df9af..a25de0319 100644 --- a/src/UI/SlotArea.h +++ b/src/UI/SlotArea.h @@ -479,7 +479,7 @@ protected: virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override; /** Called after an item has been brewed to handle statistics etc. */ - void HandleBrewedItem(cPlayer & a_Player); + void HandleBrewedItem(cPlayer & a_Player, const cItem & a_ClickedItem); } ; diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 6797d196a..e00e7aa3c 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -205,6 +205,7 @@ void cNBTChunkSerializer::AddBrewingstandEntity(cBrewingstandEntity * a_Brewings AddItemGrid(a_Brewingstand->GetContents()); m_Writer.EndList(); m_Writer.AddShort("BrewTime", a_Brewingstand->GetTimeBrewed()); + m_Writer.AddShort("Fuel", a_Brewingstand->GetRemainingFuel()); m_Writer.EndCompound(); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 54ee5b1da..971c6d88c 100755 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -944,6 +944,14 @@ cBlockEntity * cWSSAnvil::LoadBrewingstandFromNBT(const cParsedNBT & a_NBT, int std::unique_ptr Brewingstand(new cBrewingstandEntity(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World)); + // Fuel has to be loaded at first, because of slot events: + int Fuel = a_NBT.FindChildByName(a_TagIdx, "Fuel"); + if (Fuel >= 0) + { + Int16 tb = a_NBT.GetShort(Fuel); + Brewingstand->SetRemainingFuel(tb); + } + // Load slots: for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child)) { @@ -964,11 +972,11 @@ cBlockEntity * cWSSAnvil::LoadBrewingstandFromNBT(const cParsedNBT & a_NBT, int if (BrewTime >= 0) { Int16 tb = a_NBT.GetShort(BrewTime); - Brewingstand->setTimeBrewed(tb); + Brewingstand->SetTimeBrewed(tb); } // Restart brewing: - Brewingstand->GetRecipes(); + Brewingstand->LoadRecipes(); Brewingstand->ContinueBrewing(); return Brewingstand.release(); } -- cgit v1.2.3